package cn.tedu.charging.user.service;

import cn.tedu.charging.common.constant.AppInfoConst;
import cn.tedu.charging.common.enums.VehicleUserBindEnum;
import cn.tedu.charging.common.pojo.param.ChargeParam;
import cn.tedu.charging.common.pojo.param.VehicleBindParam;
import cn.tedu.charging.common.pojo.po.ChargingUserInfoPO;
import cn.tedu.charging.common.pojo.po.ChargingUserVehicleBindPO;
import cn.tedu.charging.common.pojo.po.ChargingVehiclePO;
import cn.tedu.charging.common.pojo.vo.BalanceVO;
import cn.tedu.charging.common.pojo.vo.VehicleVO;
import cn.tedu.charging.user.dao.repository.UserRepository;
import cn.tedu.charging.user.dao.repository.UserVehicleRepository;
import cn.tedu.charging.user.dao.repository.VehicleRepository;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Date;

@Service
@Slf4j
public class UserService {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private VehicleRepository vehicleRepository;
    @Autowired
    private UserVehicleRepository userVehicleRepository;
    RestTemplate restTemplate = new RestTemplate();

    //准备好即将发起 查询用户openId请求的url
    String url="https://api.weixin.qq.com/sns/jscode2session?appId={1}&secret={2}&js_code={3}&grant_type=authorization_code";
    //准备好本地的appId secret2个值
    public Integer wxLogin(String code, String nickName) {
        //1.获取一个openId 发起get请求 向qq授权服务器 提交appId以及secret以及code
        String result = restTemplate.getForObject(
                url, String.class,
                AppInfoConst.APP_ID,
                AppInfoConst.APP_SECRET,
                code);
        log.info("授权服务器反馈结果:{}",result);
        String openId=null;
        if (result!=null&&result.length()>0){
            //获取到了数据 解析 openid 使用fastjson
            JSONObject jsonObject = JSON.parseObject(result);
            //key-value session_key=si230cvouTVKco7/HtbAFA== openid=oPQKi6UKeeTdwolF3qivHOuZoNC8
            openId= (String) jsonObject.get("openid");
        }
        //2.判断是否可以从返回值当中 拿到openId 拿不到 抛异常RuntimeException
        if (openId==null||openId.length()==0){
            throw new RuntimeException("拿不到合法的openId");
        }
        //3.使用openid到数据库 查询是否有关联绑定的用户
        ChargingUserInfoPO userInfoPO=userRepository.getUserByOpenId(openId);
        //4.如果有user 则直接返回id 如果没有user 说明第一次登录 组织PO写入数据库 利用mybatis id回填获取id
        if (userInfoPO!=null){
            return userInfoPO.getId();
        }else{
            userInfoPO=new ChargingUserInfoPO();
            //仔细阅读数据表格建表语句 对于非空约束 对于初始值创建 补充完成
            userInfoPO.setWxOpenId(openId);
            userInfoPO.setNickName(nickName);
            userInfoPO.setCreateTime(new Date());
            userInfoPO.setUpdateTime(new Date());
            userRepository.save(userInfoPO);
            //mybatis对于自增注解 @TableId(type = IdType.AUTO) 会新增之后 把自增的id填补会po对象
            return userInfoPO.getId();
        }
    }

    public VehicleVO bindedVehicle(Integer userId) {
        //select v.* from charging_vehicle v inner join
        //charging_user_vehicle_bind b on v.id=b.vehicle_id where b.user_id=? and b.state=1
        //1.获取用户绑定的车辆
        Integer vehicleId=userVehicleRepository.getUserBindedVehicleId(userId,VehicleUserBindEnum.BINDED.getState());
        //2.如果没有值
        VehicleVO vo=new VehicleVO();
        if (vehicleId!=null){
            //3.查询 车辆PO
            ChargingVehiclePO po=vehicleRepository.getVehicleById(vehicleId);
            if (po!=null){
                //VehicleVO vo=new VehicleVO();
                BeanUtils.copyProperties(po,vo);
                return vo;
            }
        }
        return vo;
    }

    public Integer bindVehicle(VehicleBindParam param) {
        //1.查询 参数中 userId是否已经存在绑定的车辆
        Integer vehicleId = userVehicleRepository.getUserBindedVehicleId
                (param.getUserId(), VehicleUserBindEnum.BINDED.getState());
        //2.非空 异常结束 提示 已经绑定 请先解绑
        if (vehicleId!=null){
            throw new RuntimeException("已经绑定了车辆 请先解绑");
        }
        //3.检查该车牌号码是否已经在系统存在 select * from charging_vehicle where license=?
        ChargingVehiclePO vehicle=vehicleRepository.getVehicleByLicense(param.getLicense());
        //4.判断 空 非空
        if (vehicle==null){
            //5.组织 po数据 写入到vehicle 得到id
            vehicle=new ChargingVehiclePO();
            //补充数据 拷贝 补充2个时间
            BeanUtils.copyProperties(param,vehicle);
            vehicle.setCreateTime(new Date());
            vehicle.setUpdateTime(new Date());
            //新增 insert into charging_vehicle values (?,?,?,?,?,?,?,?)
            vehicleRepository.save(vehicle);
        }
        //6.不管非空 还是空 当前vehicle都要和用户绑定了 使用userId vehicleId
        ChargingUserVehicleBindPO userVehicle=new ChargingUserVehicleBindPO();
        userVehicle.setUserId(param.getUserId());
        userVehicle.setVehicleId(vehicle.getId());
        userVehicle.setState(1);
        userVehicle.setCreateTime(new Date());
        //insert into  charging_user_vehicle_bind values (?,?,?,?,?)
        userVehicleRepository.save(userVehicle);
        return vehicle.getId();
    }

    public void unbindVehicle(Integer userId) {
        boolean result=userVehicleRepository.updateUserVehicleState(userId);
        if (!result){
            throw new RuntimeException("解绑失败");
        }
    }

    public BalanceVO balance(Integer userId) {
       ChargingUserInfoPO po= userRepository.getUserById(userId);
       if (po==null){
           throw new RuntimeException("用户不存在");
       }
       BalanceVO vo=new BalanceVO();
       vo.setBalance(po.getBalance());
       return vo;
    }

    public void charge(ChargeParam param) {
        userRepository.updateBalanceByUserId(param);
    }
}
